package it.okkam.importChanges;

import it.okkam.importChanges.CoordinateConversion;
import it.okkam.importChanges.Punto;
import it.okkam.importChanges.Vertice;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Date;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.TimeZone;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import jena.schemagen;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;

public class ImportChanges {
	
	public static void main(String[] args) {
	ImportChanges datiCambiamenti = new ImportChanges();
	List<EventoCambiamento> lista = datiCambiamenti.leggiCambiamenti("/home/okkam/Nicola/Dati catastali completi/folgaria_camb.txt");
	File cambiamentiFile = datiCambiamenti.creaFileRDF("provaAgo2012", lista, "TURTLE");
	}
	
public List<EventoCambiamento> leggiCambiamenti(String filePoligoniCambiamentiPath) {
		
		ArrayList<EventoCambiamento> listaCambiamenti = new ArrayList<EventoCambiamento>();
		ArrayList<String> contenutoFileCambiamenti = null;
		ApriStream apriStream = new ApriStream();
		
		//lettura file 
		contenutoFileCambiamenti =  apriStream.apriStream(filePoligoniCambiamentiPath); // lettura file Poligoni
	
		// creazione liste 
		listaCambiamenti = leggiCambiamenti(contenutoFileCambiamenti);
				
		return listaCambiamenti;	
		
		}

private  ArrayList<EventoCambiamento>    leggiCambiamenti(List<String> contenutoFileCambiamenti){
	ArrayList<EventoCambiamento> listaEventiLettura = new ArrayList<EventoCambiamento>();
	Date dataCambiamento= null; 
		
	List<List<Vertice>> listaPuntiPoligono = new ArrayList<List<Vertice>>();
	String tipoCambiamento = null;
	int indiceOrdine = 0;
	XMLGregorianCalendar newCal = null;
	List<Vertice> puntiPoligono = new ArrayList<Vertice>();
	for(String rigaLetta:contenutoFileCambiamenti)	{
		
		//gestione data
		if (rigaLetta.startsWith("Data")){
			//caso data
			rigaLetta = rigaLetta.substring(5);
			DateFormat pattern = new SimpleDateFormat("dd/MM/yyyy");
	        try {
	            Date exampleDateObj = pattern.parse(rigaLetta);
	            GregorianCalendar c = new GregorianCalendar();
	            c.setTime(exampleDateObj);
	            c.get(Calendar.DAY_OF_WEEK);
	            
	            newCal= DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
	            newCal.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
	            newCal.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
	            //System.out.println(newCal.toXMLFormat());
	        } catch (ParseException e) {
	            e.printStackTrace();
	        } catch (DatatypeConfigurationException e) {
				e.printStackTrace();
			}
		}
		else {
			if (rigaLetta.equals("END") ){				
					//fine poligono
					Poligono poligonoLetto = new Poligono();
					List<Vertice> newPoligono =new ArrayList<Vertice>();
					for(Vertice v:puntiPoligono)
						newPoligono.add(v);
					poligonoLetto.setPoligono(newPoligono); // carico i punti del poligono 
					
					// creo la particella e la popolo
					EventoCambiamento eventoCambiamentoLetto = new EventoCambiamento();
					eventoCambiamentoLetto.setPoligono(poligonoLetto);
					eventoCambiamentoLetto.setTipoCambiamento(tipoCambiamento);
					eventoCambiamentoLetto.setDataCambiamento(newCal);
					
					// carico la particella sulla lista delle particelle lette
					listaEventiLettura.add(eventoCambiamentoLetto);
					
					// mi preparo a leggere un'altra particella 
					indiceOrdine = 0;
					//listaPuntiPoligono.add(new ArrayList<Vertice>(puntiPoligono));
					puntiPoligono.clear();
					}
			if (rigaLetta.startsWith("n")||rigaLetta.startsWith("e")||rigaLetta.startsWith("A")){
				tipoCambiamento = rigaLetta;
			}
			if (rigaLetta.startsWith("0")){
											
						Vertice vertice = new Vertice();
						indiceOrdine++;
						vertice = leggiVertice(rigaLetta, indiceOrdine);
						puntiPoligono.add(vertice);
						}
		}
}	return listaEventiLettura;
}



private  Vertice   leggiVertice (String lettura , int indice){
	Vertice vertex = new Vertice();
	Punto puntoLetto = new Punto();
	
	StringTokenizer st = new StringTokenizer(lettura, " "); 
	while(st.hasMoreTokens()){
		String coordX = st.nextToken();
		String coordY = st.nextToken();
		double cX = convertiTestoToNumero(coordX);
		
		double cY = convertiTestoToNumero(coordY);
		double lat = cX;
		double lon = cY;
		//double lat= utm2Lat(cX, cY, "32 T "/*NORD_ITALIA*/);
		//double lon= utm2Lon(cX, cY,"32 T "/* NORD_ITALIA*/);
		puntoLetto.setX( lat);
		puntoLetto.setY( lon );
//		System.out.println(lat + " " + lon);
		vertex.setVertice(puntoLetto);
		vertex.setCardinalita(indice);}
	
	return vertex;
}	
private  double   utm2Lat (Double utmLat, Double utmLon, String zona){
	
	CoordinateConversion converter = new CoordinateConversion();
	
	String utmLatStr = Double.toString(utmLat);
	String utmLonStr = Double.toString(utmLon);
	String utmCoordinates = zona +  utmLatStr + " " + utmLonStr;
	
	double[] latLon = converter.utm2LatLon(utmCoordinates);
	
	double lat = latLon[0];
	return lat;
	
}
private  double   utm2Lon (Double utmLat, Double utmLon, String zona){
	
	CoordinateConversion converter = new CoordinateConversion();
	
	String utmLatStr = Double.toString(utmLat);
	String utmLonStr = Double.toString(utmLon);
	String utmCoordinates = zona  + utmLatStr + " " + utmLonStr;
	
	double[] latLon = converter.utm2LatLon(utmCoordinates);
	double longitudine = latLon[1];
					
	return longitudine;
}
public double convertiTestoToNumero (String coordinataTestuale){
	double coordinata= 0;
	int potenza;
	String radice, segno, potenzaStringa;
	if(coordinataTestuale!=null){
		//estraggo la radice della coordinata 
		int indice = coordinataTestuale.indexOf('E');
		radice = coordinataTestuale.substring(0, indice);
		coordinata = Double.parseDouble(radice);
		//estraggo il segno della potenza
		segno = coordinataTestuale.substring((indice+1), (indice+2));
		//estraggo l'esponente 		
		potenzaStringa = coordinataTestuale.substring(indice+2);
		potenza = Integer.parseInt(potenzaStringa);
		
		// adegue l'esponente al segno
			if (segno.equals("-"))
				potenza = potenza * (-1);
		// calcolo la coordinata
		coordinata = coordinata * (Math.pow(10, potenza));
				
		return coordinata;
	}
	else return 0.0;
}
public File creaFileRDF(String nomeFile, List<EventoCambiamento> listaCambiamenti, String serializzazione) {
	// TODO Auto-generated method stub
	File fileCambiamentirdf = new File("/home/okkam/Nicola/Dati catastali completi/cambiamenti"+ nomeFile +".rdf");
	Model model = ModelFactory.createDefaultModel();
	String ontologia = "http://www.okkam.it/ont/particella_catastale.owl";
	model.setNsPrefix("pc", "http://www.okkam.it/ont/particella_catastale.owl#"); // set del prefisso
	
	for(EventoCambiamento eventoCambiamento:listaCambiamenti){
		
		String poligonoURI = null;
		String puntoURI = null;
		String verticeURI = null;
		String cambiamentoURI = null;
	
		Poligono poligonoLetto = eventoCambiamento.getPoligono();
		
		
		//particellaRisorsa.addProperty(Schemagen.haCentro, puntoURI);
		
		poligonoURI = creaURIPoligono(ontologia, poligonoLetto);
		Resource poligonoRisorsa = model.createResource(poligonoURI);
		//System.out.println(eventoCambiamento.getDataCambiamento());
		String data = eventoCambiamento.getDataCambiamento().toXMLFormat();
		//System.out.println(data);
		cambiamentoURI = creaURICambiamento(ontologia, poligonoLetto, data);
		Resource cambiamentoRisorsa = model.createResource(cambiamentoURI);
		cambiamentoRisorsa.addProperty(Schemagen.haPoligono, poligonoRisorsa);
		cambiamentoRisorsa.addProperty(Schemagen.haDataAcquisizione, data);
		cambiamentoRisorsa.addProperty(Schemagen.haTipoCambiamento, eventoCambiamento.getTipoCambiamento());//?
	
		List<Vertice> listaVertici = poligonoLetto.getPoligono();
		
		for (Vertice verticeLetto: listaVertici){
				
			int ordine = verticeLetto.getCardinalita();			
			
			Punto puntoLetto = verticeLetto.getVertice();
			puntoURI = creaURIPunto(ontologia, puntoLetto);
			verticeURI = creaURIVertice(poligonoURI, puntoURI, ontologia, Integer.toString(ordine));
			Resource verticeRisorsa = model.createResource(verticeURI);	
			Resource puntoRisorsa = model.createResource(puntoURI);
			puntoRisorsa.addProperty(Schemagen.haLatitudineWGS84Decimale, Double.toString(puntoLetto.getX()));
			puntoRisorsa.addProperty(Schemagen.haLongitudineWGS84Decimale, Double.toString(puntoLetto.getY()));
			verticeRisorsa.addProperty(Schemagen.haPunto, puntoRisorsa);
			verticeRisorsa.addProperty(Schemagen.haNumeroOrdine, Integer.toString(ordine));
			//verticeRisorsa.addLiteral(Schemagen.haNumeroOrdine, Integer.toString(ordine));
			poligonoRisorsa.addProperty(Schemagen.haVertice, verticeURI);
		
		}
		
	}
	
	try{
	model.write(new PrintWriter(fileCambiamentirdf), serializzazione);
	}
	catch(FileNotFoundException e) {			
		e.printStackTrace();
	}
	System.out.println("Creazione file " + fileCambiamentirdf.getName() +" terminata!");
	//System.out.println("Il file " + fileLavisrdf.getName() + " "+ fileLavisrdf.length());
	return fileCambiamentirdf;
}

private String creaURIPunto(String ontologia, Punto punto){
	String URIpunto = null; 
	ontologia = ontologia + "/punto";
	
	URIpunto = ontologia + "/lat/" + getParteIntera(punto.getX()) + "/" + getParteFrazionaria(punto.getX()) + "/lon/" + getParteIntera(punto.getY()) + "/" +getParteFrazionaria(punto.getY()) + "/wgs84"; 
	
	return URIpunto;
}
private String getParteIntera (double numero){
	String intera=null;
	String numeroStr = Double.toString(numero);
	int punto = trovaPosizionePunto(numeroStr);
	intera = numeroStr.substring(0,punto);
	return intera;
}

private String getParteFrazionaria (double numero){
	String fraz=null;
	String numeroStr = Double.toString(numero);
	int punto = trovaPosizionePunto(numeroStr);
	fraz = numeroStr.substring(punto+1);
	return fraz;
}
private int trovaPosizionePunto (String stringaIndagata){
	int i= 0;
	for (int j=0; j < stringaIndagata.length() ; j++  ){
		if (stringaIndagata.charAt(j)=='.'){
			i=j;
		}
	}
	return i;
	
}
private String creaURIVertice (String URIpoligono , String URIpunto , String URIontologia , String ordine ){
	String URIvertice = URIpoligono;
	int URIverticeSize = URIvertice.length()-1;
	URIvertice = URIvertice.substring(0, URIverticeSize);
	//System.out.println(URIvertice);
	
	int indice = URIontologia.length();
	String subURI = URIpunto.substring(indice);
	URIvertice = URIvertice + subURI + "/w/" + ordine;		
	return URIvertice;

}
private String creaURICambiamento (String URIontologia , Poligono poligonoLetto , String data){
	String URIcambiamento = null;

	URIcambiamento = creaURIPoligono(URIontologia, poligonoLetto) + data ;
	
	return URIcambiamento;

}

private String creaURIPoligono(String ontologia, Poligono poligonoLetto){
	String URIpoligono = null; 
	ontologia = ontologia;
	List<Vertice> listaVertici = poligonoLetto.getPoligono();
	Vertice primoVertice = listaVertici.get(0);
	Vertice secondoVertice = listaVertici.get(1);
	Punto primoPunto = primoVertice.getVertice();
	Punto secondoPunto = secondoVertice.getVertice();
	
	URIpoligono = ontologia + "/poligono/lat/" + getParteIntera(primoPunto.getX()) + "/" + getParteFrazionaria(primoPunto.getX()) + "/lon/" + getParteIntera(primoPunto.getY()) + "/" +getParteFrazionaria(primoPunto.getY()) + "/wgs84/";
	URIpoligono = URIpoligono + "lat/" + getParteIntera(secondoPunto.getX()) + "/" + getParteFrazionaria(secondoPunto.getX()) + "/lon/" + getParteIntera(secondoPunto.getY()) + "/" +getParteFrazionaria(secondoPunto.getY()) + "/wgs84/";
	
	return URIpoligono;
}	
}
